/*
 * html2view.c
 *
 *  Created on: Aug 30, 2009
 *      Author: jacky
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#define START_BLOCK "<%"
#define END_BLOCK "%>"

enum status
{
	OK, FAIL, FILE_NOEXT
};
static struct config
{
	char *input_filename;
	char *output_filename;
	char *viewname;
	FILE *out;

} conf =
{ NULL, NULL, NULL, NULL };
static void usage()
{
	puts("usage");
	puts("html2view -i html_file -o c_file\n");
}
int parse_args(int argc, char **argv)
{
	int argn = 1;
	enum status result = OK;
	if (1 == argc)
	{
		result = FAIL;
		usage();
	}

	while (argn < argc && argv[argn][0] == '-')
	{
		if (strcmp(argv[argn], "-i") == 0 && argn + 1 < argc)
		{
			++argn;
			conf.input_filename = argv[argn];
		}
		else if (strcmp(argv[argn], "-v") == 0 && argn + 1 < argc)
		{
			++argn;
			conf.viewname = argv[argn];
		}
		else if (strcmp(argv[argn], "-o") == 0 && argn + 1 < argc)
		{
			++argn;
			conf.output_filename = argv[argn];
		}
		else
		{
			usage();
		}
		++argn;
	}
	return result;
}

static void htmlOutput(const char *html)
{
	const char *p = html;
	/* html code */
	fprintf(conf.out, "fprintf(response->Out,\"%%s\",\"");
	while (*p)
	{
		switch (*p)
		{
		case '"':
			fputc('\\', conf.out);
			break;
		case '\n':
			fputc('\\', conf.out);
			fputc('n', conf.out);
			p++;
			continue;
			break;
		default:
			break;
		}
		fputc(*p, conf.out);
		p++;
	}

	fprintf(conf.out, "\");\n");
}
static void cCodeOutput(const char* cCode)
{
	if (cCode)
		fprintf(conf.out, "%s", cCode);
}
static void out(char *buf)
{
	char *s = NULL;
	static int is_html = 1;

	if ((s = strstr(buf, START_BLOCK)) != NULL)
	{
		*s = '\0';
		s += strlen(START_BLOCK);
		htmlOutput(buf);
		is_html = 0;
		out(s);
		return;
	}
	if ((s = strstr(buf, END_BLOCK)) != NULL)
	{
		*s = '\0';
		s += strlen(END_BLOCK);
		cCodeOutput(buf);
		is_html = 1;
		out(s);
		return;
	}
	if (is_html)
	{
		htmlOutput(buf);
	}
	else
	{
		cCodeOutput(buf);
	}

}
static int getFileSize(FILE *file)
{
	struct stat buf;
	fstat(fileno(file), &buf);
	return buf.st_size;
}
static void creatfile()
{
	FILE *fp;
	char *buf;
	int filesize;

	fprintf(
			conf.out,
			"/* this file is auto created by html2view tool from %s Don't modfiy */\n",
			conf.input_filename);
//	fprintf(conf.out, "#include <stdio.h>\n");
//	fprintf(conf.out, "#include \"controllers/controller.h\"\n");
//	fprintf(conf.out, "#include \"views/view.h\"\n");
//	fprintf(conf.out, "DEFINE_VIEW(%s)\n{", conf.viewname);

	if ((fp = fopen(conf.input_filename, "r")))
	{
		filesize = getFileSize(fp);
		if (filesize > 0)
		{
			if ((buf = (char*) malloc(filesize + 1)))
			{
				fread(buf, filesize, 1, fp);
				out(buf);
				free(buf);
			}
			else
			{
				printf("error");
			}
		}

		fclose(fp);
	}
//	fprintf(conf.out, "}");
}
int main(int argc, char **argv)
{
	int result = OK;

	if (!(result = parse_args(argc, argv)))
	{

		if (access(conf.input_filename, R_OK))
		{
			result = FILE_NOEXT;
			printf("input file can not read.\n");
		}
		else
		{
			if (NULL != conf.output_filename)
			{
				if (!(conf.out = fopen(conf.output_filename, "w")))
				{
					conf.out = stdout;
				}
			}

			creatfile();

			if (conf.out != stdout)
			{
				fclose(conf.out);
			}
		}
	}

	return result;
}
